Skip to content

SPIKE: Protocol 29 (CAP-0088) - #227

Draft
sisuresh wants to merge 1 commit into
stellar:protocol-nextfrom
sisuresh:p30-cap-0088
Draft

SPIKE: Protocol 29 (CAP-0088)#227
sisuresh wants to merge 1 commit into
stellar:protocol-nextfrom
sisuresh:p30-cap-0088

Conversation

@sisuresh

Copy link
Copy Markdown
Contributor

Changes

  • Bump MaxSupportedProtocolVersion to 29 and repin go-stellar-sdk to the CAP-0088 XDR regen (Protocol 30 (CAP-0088) go-stellar-sdk#5998, e66bca6a), which adds the STELLAR_VALUE_SIGNED_MS/EMPTY_TX_SET_MS arms. No Horizon code switches on that discriminant; close times stay whole-second and closeTimeMs is not exposed.
  • Re-baseline internal/ingest/testdata/test-lcms/ from stellar-core#5423 test-lcm-next (+3 suites, +279 fixtures).
  • CI: roll the integration window to {28, 29}; P29 builds core from refs/pull/5423/head since no -vnext artifact exists, with an empty stellar-rpc image (guarded pull → AMBER skip).

Deferred

  • TestCoreLCMIngestion is RED: 807/1134 fixtures fail to decode — a stellar-core#5423 defect, left failing deliberately. That PR's head bumped its XDR submodule to 03cbf40c (closeTimeMs uint32uint64) but did not re-record test-lcm-next/. See comment below.
  • Protocol number is 29, not the 30 in the release brief — core#5423 sets MAX_SUPPORTED_PROTOCOL_VERSION 28+1. Needs a ruling; renumbering is an upstream core change.
  • load-test-{ledgers,fixtures}-v29.xdr.zstd are copies of the v28 recordings; they pass but do not exercise ms close times. Regenerate once a P29 ~vnext~buildtests core image exists.

Upstream: stellar/go-stellar-sdk#5998, stellar/stellar-core#5423

Repin go-stellar-sdk to the CAP-0088 XDR regeneration (stellar/go-stellar-sdk#5998,
e66bca6a) and bump MaxSupportedProtocolVersion to 29. The regen is what makes the
new STELLAR_VALUE_SIGNED_MS / STELLAR_VALUE_EMPTY_TX_SET_MS StellarValue.ext arms
decodable; the SDK's ValidEnum and view types reject unknown discriminants, so
every LedgerCloseMeta consumer needs it.

Horizon has no switch on the StellarValue ext discriminant. Its only two reads of
scpValue are the whole-second closeTime (db2/history/ledger.go, trades_processor.go),
which CAP-0088 leaves unchanged, so closeTimeMs is deliberately not plumbed through
or exposed.

The pin is a replace directive to the fork because #5998 is unmerged and e66bca6a
is not reachable from any ref in stellar/go-stellar-sdk.

CI: roll the integration window to {28, 29}. P29 builds core from
stellar-core#5423 (refs/pull/5423/head) since no -vnext image or deb is built from
it; Dockerfile.testing enables the next protocol version, which is what makes 29
reachable. Its stellar-rpc image is empty (none published for 29), so guard the
pull step and let NewTest()'s AMBER skip fire rather than run against a P28 RPC
that cannot ingest P29.

Re-baseline internal/ingest/testdata/test-lcms/ from stellar-core#5423's
test-lcm-next, adding the BumpSequenceTests, ClaimableBalanceTests and HerderTests
suites. 807 of these fixtures currently fail to decode; see the PR discussion for
the upstream defect this surfaces.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sisuresh

Copy link
Copy Markdown
Contributor Author

⚠️ UPSTREAM BLOCKER (stellar-core#5423): test-lcm-next/ fixtures are stale — 807/1134 fail to decode. Left failing deliberately, per the "never route around a fixture failure" rule. This is not a Horizon or go-stellar-sdk bug.

What's wrong. stellar-xdr changed the MS arms between two commits:

96cbfc37 (old) 03cbf40c (current)
closeTimeMs uint32 — ms component, [0,999] TimePointMilliseconds (uint64) — full unix ms

stellar-core#5423 has 3 commits. test-lcm-next/ was last written by 1067bb69 (2026-08-19), when the XDR submodule was 96cbfc37. The head commit 9ef9b5cd bumped the submodule to 03cbf40c without re-recording the fixtures, so every MS-bearing fixture is encoded with the old 4-byte field while every consumer of 03cbf40c expects 8. Decoding shears by 4 bytes.

decoding LedgerCloseMetaV2: decoding LedgerHeaderHistoryEntry: decoding LedgerHeader:
decoding StellarValue: decoding StellarValueExt: decoding StellarValueSignedMsValue:
decoding LedgerCloseValueSignature: decoding NodeId: decoding PublicKey:
decoding PublicKeyType: '15895259' is not a valid PublicKeyType enum value

Byte-level prooftest-lcm-next/HerderTests/370dd5e0af5cfa8d.xdr, scpValue.ext = 4 (EMPTY_TX_SET_MS) at 0x7c. Parsed with the old layout every field is self-consistent:

offset old layout value
0x80 uint32 closeTimeMs 1 — valid ms component in [0,999]
0x84 Hash txSetHash
0xa4 Hash previousLedgerHash 6e310c5c…136abyte-identical to the header's previousLedgerHash at 0x30
0xc4 uint32 previousLedgerVersion 29 — matches ledgerVersion
0xc8 PublicKeyType 0 = PUBLIC_KEY_TYPE_ED25519
0xe8 signature length 64

Under the new layout the reader consumes 8 bytes at 0x80 and lands 4 bytes late, reading 0x03e5a6c3 = 65382083 as PublicKeyType — exactly the reported error. closeTimeMs also decodes to 7303299291 under the new layout, which is neither a valid ms component nor a plausible unix-ms timestamp (closeTime is 15).

Blast radius: 807 of 1134 fixtures. The 327 that decode carry only STELLAR_VALUE_SIGNED (ext=1) — i.e. every fixture that actually exercises CAP-0088 is unreadable, so protocol-29 LCM ingestion is currently unverified.

Fix (upstream, not here): re-run the --capture-lcm capture on stellar-core#5423 with the submodule at 03cbf40c and re-commit test-lcm-next/. This PR will go green on a straight re-copy — no Horizon change needed. I did not delete, skip or trim any fixture.

Verified independently of the DB harness with a decode-only scan against the pinned SDK; all other Horizon tests pass (go test ./... is green except this one test).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant